package com.dome.aspect;

import com.dome.annotation.Idempotence;
import com.dome.common.utils.RedisUtils;
import com.dome.exception.CommonException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * @param
 * @author tangshunkai
 */
@Slf4j
@Aspect
@Component
public class IdempotenceAop {

    @Autowired
    private RedisUtils redisUtil;

    @Pointcut("@annotation(com.dome.annotation.Idempotence)")
    public void testAop(){ }

    /**
     * 环绕通知验证参数
     * @param point
     * @return
     * @throws Throwable
     */
    @Around("testAop()")
    public Object testAopEx(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Idempotence apiIdempotent = signature.getMethod().getDeclaredAnnotation(Idempotence.class);
        if (apiIdempotent != null) {
            return apiIdempotent(point, signature);
        }
        Object proceed = point.proceed();
        return proceed;
    }

    private Object apiIdempotent(ProceedingJoinPoint point, MethodSignature signature) throws Throwable {
        Idempotence apiIdempotent = signature.getMethod().getDeclaredAnnotation(Idempotence.class);
        if (apiIdempotent == null) {
            // 直接执行程序
            Object proceed = point.proceed();
            return proceed;
        }
        // 代码步骤：
        // 1.获取令牌 存放在请求头中
        HttpServletRequest request = getRequest();
        String valueType = apiIdempotent.type();
        if (StringUtils.isEmpty(valueType)) {
            log.info("注解参数错误!");
            throw new CommonException("注解参数错误");
        }
        String token = null;
        if (valueType.equals("head")) {
            token = request.getHeader("token");
        } else {
            token = request.getParameter("token");
        }
        if (StringUtils.isEmpty(token)) {
            log.info("缺少幂等性校验token!");
            throw new CommonException("缺少幂等性校验token!");
        }
        if (!Objects.isNull(redisUtil.get(token))){
            System.out.println("打印redis的数据："+redisUtil.get(token));
            log.info("toke:"+token);
            log.info("请勿重复提交!");
            throw new CommonException("请勿重复提交!");
        }
        Object proceed = point.proceed();
//        redisUtil.del(token);
        return proceed;
    }

    public HttpServletRequest getRequest() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        return request;
    }
}
